package me.linzh;

import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Set;

/**
 * 处理异步socketIO的reactor线程
 * Created by leolin on 15/12/31.
 */
public class ReactorTask implements Runnable {


    private Selector selector;
    private int selectTimeout = 0;
    private SelectedKeyHandler connectHandler;
    private SelectedKeyHandler acceptHandler;
    private SelectedKeyHandler readHandler;
    private SelectedKeyHandler writeHandler;

    private ReactorTask(){}
    public ReactorTask(Selector selector){
        this.selector = selector;
    }

    @Override
    public void run() {
        while (true) {
            try {
                if (selector.select(10) == 0) {
                    continue;
                }
            } catch (ClosedSelectorException ex) {
                System.out.println("【NIO demo】select closed, ReactorTaskStop" + ex.toString());
                return;
            } catch (IOException | IllegalArgumentException ignore) {
                ignore.printStackTrace();
//                    忽略IO异常和参数异常
            }


            Set<SelectionKey> selectorKeys = selector.selectedKeys();

            for (SelectionKey selectorKey : selectorKeys) {
                if (!selectorKey.isValid()) {
                    continue;
                }
                // IO处理
                if (acceptHandler != null && selectorKey.isAcceptable()) {
                    acceptHandler.handle(selectorKey);
                }
                if (connectHandler != null && selectorKey.isConnectable()) {
                    connectHandler.handle(selectorKey);
                }
                if (readHandler != null && selectorKey.isReadable()) {
                    readHandler.handle(selectorKey);
                }
                if (writeHandler != null && selectorKey.isWritable()) {
                    writeHandler.handle(selectorKey);
                }
            }
        }
    }

    public void setSelector(Selector selector) {
        this.selector = selector;
    }

    public void setSelectTimeout(int selectTimeout) {
        this.selectTimeout = selectTimeout;
    }

    public void setConnectHandler(SelectedKeyHandler connectHandler) {
        this.connectHandler = connectHandler;
    }

    public void setAcceptHandler(SelectedKeyHandler acceptHandler) {
        this.acceptHandler = acceptHandler;
    }

    public void setReadHandler(SelectedKeyHandler readHandler) {
        this.readHandler = readHandler;
    }

    public void setWriteHandler(SelectedKeyHandler writeHandler) {
        this.writeHandler = writeHandler;
    }

}
